﻿// Decompiled with JetBrains decompiler
// Type: Netick.NetickWorker
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System;
using System.Collections.Generic;
using System.Threading;

#nullable disable
namespace Netick;

internal class NetickWorker
{
  internal NetickEngine Engine;
  internal Thread Thread;
  internal bool HasFinished = true;
  internal AutoResetEvent Signaler = new AutoResetEvent(false);
  internal SerializationCache Cache;
  internal Queue<ServerConnection> Clients;
  private Queue<ServerConnection> _clisQueue;

  public NetickWorker(NetickEngine engine, bool isMainThread = false)
  {
    this.Engine = engine;
    this.Clients = new Queue<ServerConnection>(engine.MaxPlayers);
    this._clisQueue = new Queue<ServerConnection>(engine.MaxPlayers);
    this.Cache = new SerializationCache(engine);
    if (isMainThread)
      return;
    this.Thread = new Thread(new ThreadStart(this.Main))
    {
      IsBackground = true
    };
    this.Thread.Name = "Netick Thread";
    this.Thread.Start();
  }

  internal void Write(List<ServerConnection> clients, NetickWorker[] PacketWriters)
  {
    List<ServerConnection> serverConnectionList = clients;
    int num1 = Math.Max(1, Math.Min(clients.Count, PacketWriters.Length));
    int num2 = clients.Count / num1;
    int num3 = clients.Count % num1;
    this._clisQueue.Clear();
    for (int index = 0; index < serverConnectionList.Count; ++index)
      this._clisQueue.Enqueue(serverConnectionList[index]);
    ServerConnection serverConnection1;
    for (int index = 0; index < num2 && this._clisQueue.TryDequeue(ref serverConnection1); ++index)
      this.Clients.Enqueue(serverConnection1);
    for (int index1 = 0; index1 < PacketWriters.Length; ++index1)
    {
      PacketWriters[index1].HasFinished = false;
      int num4 = index1 == PacketWriters.Length - 1 ? 1 : 0;
      int num5 = num2;
      if (num4 != 0)
        num5 += num3;
      ServerConnection serverConnection2;
      for (int index2 = 0; index2 < num5 && this._clisQueue.TryDequeue(ref serverConnection2); ++index2)
        PacketWriters[index1].Clients.Enqueue(serverConnection2);
    }
    for (int index = 0; index < PacketWriters.Length; ++index)
      PacketWriters[index].Signaler.Set();
    ServerConnection serverConnection3;
    while (this.Clients.TryDequeue(ref serverConnection3))
      serverConnection3.WritePacketsSecondPass(this.Cache);
    bool flag;
    do
    {
      flag = true;
      for (int index = 0; index < PacketWriters.Length; ++index)
      {
        if (!PacketWriters[index].HasFinished)
          flag = false;
      }
    }
    while (!flag);
  }

  private void Main()
  {
    try
    {
      while (this.Engine.IsRunning)
      {
        this.Cache.Clear();
        ServerConnection serverConnection;
        while (this.Clients.TryDequeue(ref serverConnection))
          serverConnection.WritePacketsSecondPass(this.Cache);
        this.HasFinished = true;
        this.Signaler.WaitOne();
      }
      this.HasFinished = true;
    }
    catch (Exception ex)
    {
      this.HasFinished = true;
    }
  }
}
